package com.homevip.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;

/**
 * 二维码生成工具类
 * @author root
 *
 */
public class ZxingQrcode {

	private static final String CODE = "utf-8";
	private static final int BLACK = 0xff000000;
	private static final int WHITE = 0xFFFFFFFF;

	/**
	 * 快速生成
	 * @param content 内容
	 * @param outsrc 输出路径　使用jpg
	 * @throws Exception
	 */
	public static void encoderQRCode(String content, String outsrc) throws Exception {
		encoderQRCode(content, outsrc, "jpg", 300, 300, 0, 0, 2, null);
	}
	
	/**
	 * 完整参数生成二维码
	 * @param content 生成二维码内容
	 * @param outsrc　输入图片路径
	 * @param format　图片格式 png,jpg,gif
	 * @param width 图片宽
	 * @param height 图片高
	 * @param onColor 字体颜色
	 * @param offColor　背景色
	 * @param level 0 = M ~15%, 1 = L ~7%, 2 = H ~30% 3 = Q ~25%
	 * @param charset 字符集，需要小写
	 * @throws Exception
	 */
	public static void encoderQRCode(String content, String outsrc, String format, int width, int height, int onColor, int offColor, int level, String charset) throws Exception {
		Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		if (charset == null || charset.trim().length() == 0) {
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		}
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.forBits(level));
		hints.put(EncodeHintType.MARGIN, 1);
		
		MatrixToImageConfig config = new MatrixToImageConfig(onColor, offColor);
		if (onColor == 0 && offColor == 0) {
			config = new MatrixToImageConfig();
		}
		
		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
		File outFile = new File(outsrc);
		outFile.mkdirs();
		MatrixToImageWriter.writeToFile(bitMatrix, format, new File(outsrc), config);
	}
	/**
	 * 生成一维码，写到文件中
	 *
	 * @author wuhongbo
	 * @param str
	 * @param height
	 * @param file
	 * @throws IOException
	 */
	public static void getBarcodeWriteFile(String str, Integer width,
										   Integer height, File file) throws IOException
	{
		BufferedImage image = getBarcode(str, width, height);
		ImageIO.write(image, "png", file);
	}


	/**
	 * 生成一维码（128）
	 *
	 * @author wuhongbo
	 * @param str
	 * @param width
	 * @param height
	 * @return
	 */
	public static BufferedImage getBarcode(String str, Integer width,
										   Integer height)
	{

		if (width == null || width < 200)
		{
			width = 200;
		}

		if (height == null || height < 50)
		{
			height = 50;
		}

		try
		{
			// 文字编码
			Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
			hints.put(EncodeHintType.CHARACTER_SET, CODE);

			BitMatrix bitMatrix = new MultiFormatWriter().encode(str,
					BarcodeFormat.CODE_128, width, height, hints);

			return toBufferedImage(bitMatrix);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 转换成图片
	 *
	 * @author wuhongbo
	 * @param matrix
	 * @return
	 */
	private static BufferedImage toBufferedImage(BitMatrix matrix)
	{
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_ARGB);
		for (int x = 0; x < width; x++)
		{
			for (int y = 0; y < height; y++)
			{
				image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
			}
		}
		return image;
	}

	public static void main(String [] args) throws Exception {
		encoderQRCode(UUID.randomUUID().toString().substring(0,8), "d:/"+UUID.randomUUID().toString().substring(0,32)+".jpg");
	}
}
